package com.test.satokenmongodbdemo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.IndexInfo;
import org.springframework.data.mongodb.core.index.IndexOperations;
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexResolver;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;

import java.util.List;
import java.util.Optional;

@SpringBootApplication
public class SaTokenMongodbDemoApplication {

    private final MongoTemplate mongoTemplate;

    private static final Logger logger = LoggerFactory.getLogger(SaTokenMongodbDemoApplication.class);

    public SaTokenMongodbDemoApplication(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    public static void main(String[] args) {
        SpringApplication.run(SaTokenMongodbDemoApplication.class, args);
    }

    // 初始化 索引
    @EventListener(ContextRefreshedEvent.class)
    public void initIndicesAfterStartup() {
        logger.info("init index");
        MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> context = mongoTemplate.getConverter().getMappingContext();
        MongoPersistentEntityIndexResolver resolver = new MongoPersistentEntityIndexResolver(context);

        context.getPersistentEntities().stream()
                .filter(it -> it.getType().getDeclaredAnnotation(Document.class) != null)
                .forEach(persistentEntity -> {
                    IndexOperations indexOperations = mongoTemplate.indexOps(persistentEntity.getType());
                    resolver.resolveIndexFor(persistentEntity.getType()).forEach(it -> {

                        String name = it.getIndexOptions().getString("name");

                        List<IndexInfo> indexInfoInDB = indexOperations.getIndexInfo();

                        Optional<IndexInfo> infoOptional = indexInfoInDB.stream().filter(indexInfo -> indexInfo.getName().equals(name)).findAny();
                        if (infoOptional.isEmpty()) {
                            logger.info("create name={} index={} for {}", name, it.getIndexKeys(), persistentEntity.getName());
                            indexOperations.ensureIndex(it);
                        } else {
                            IndexInfo indexInfo = infoOptional.get();
                            logger.info("skip name={} index={} for {}", name, indexInfo.getName(), persistentEntity.getName());
                        }
                    });
                });

    }
}
